﻿using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using CodeDynamiksEngine;
using CodeDynamiksCtl;
using MESCodeFile;

namespace LiveUpdateSystem
{
    //LiveUpdate Procedure
    //1. Check the available update for the application.
    //2. Get the files that will be downloaded if the version is not the same.
    class LiveUpdate
    {
        //Attributes for live updates
        List<string> FileList = new List<string>();
        string[] cfg = new string[4];
        string _errMsg = "";
        bool _hasError = false;
        
        //Exclusive Operations
        void CheckUpdateContent()
        {
            bool[] file = new bool[2];
            string[] header = new string[2];
            bool dlFiles = false;

            file[0] = File.Exists(Common.LOCPATH + "update.sys");
            file[1] = File.Exists(Common.LOCPATH + "updateNew.sys");

            if (file[0] && file[1])
            {
                try
                {
                    using (StreamReader sr = new StreamReader(File.Open(Common.LOCPATH + "update.sys", FileMode.Open)))
                    {
                        header[0] = sr.ReadLine();
                        sr.Close();
                    }
                    using (StreamReader sr = new StreamReader(File.Open(Common.LOCPATH + "updateNew.sys", FileMode.Open)))
                    {
                        header[1] = sr.ReadLine();
                        sr.Close();
                    }
                    if (!header[0].Equals(header[1])) dlFiles = true;
                }
                catch (Exception ex)
                {
                    _errMsg = ex.Message;
                    _hasError = true;
                    return;
                }
            }
            else if (!file[0] && file[1])
            {
                dlFiles = true;
            }
            else
            {
                _errMsg = "Unexpected error!";
                _hasError = true;
                return;
            }
            //Call Download Here
        }
        void DownloadFiles()
        {
            CodeScript s = new CodeScript("DOWNLOADUPDATES");
            s.Add(CodeIns.RFU_NEW_CORE);
            s.Add(CodeIns.RFU_SET_CONFIG, cfg[0], cfg[1], cfg[2], 256);
            for (int i = 0; i < FileList.Count; i++)
            {
                s.Add(CodeIns.RFU_DWLD, Common.LOCPATH + "file"+i, cfg[3] + "/" + FileList[i]);
            }
            s.Add(CodeIns.RFU_END);

            CodeProcessor p = new CodeProcessor();
            p.ProcessCompleted += new EventHandler(delegate
            {
                if (p.State == ProcessorFlag.DataRdyErr ||
                   p.State == ProcessorFlag.Error ||
                   p.State == ProcessorFlag.ReadyErr)
                {
                    _errMsg = p.GetProcessorMessage;
                    _hasError = true;
                    p.ClearErrorFlag();
                    return;
                }
                _hasError = false;
            });
            p.Run(s);
        }
        void BuildDownloadList()
        {
            //Write the filename equivalent to file
            using (StreamWriter sw = new StreamWriter(File.Open(Common.LOCPATH + "dl.sys", FileMode.Create)))
            {
                for (int i = 0; i < FileList.Count; i++)
                {
                    if (i < FileList.Count - 1)
                    {
                        sw.WriteLine("file" + i);
                        sw.WriteLine(FileList[i]);
                    }
                    else
                    {
                        sw.WriteLine("file" + i);
                        sw.Write(FileList[i]);
                    }

                }
                sw.Close();
            }
        }
        
        //Public operations
        public void SetConfig(object svr, object uid, object pwd, object appname)
        {
            cfg[0] = "ftp://" + svr.ToString();
            cfg[1] = uid.ToString();
            cfg[2] = pwd.ToString();
            cfg[3] = "AppUpdate/" + appname.ToString();
        }
        public void CheckUpdate()
        {
            CodeScript s = new CodeScript("CHECKUPDATE");
            s.Add(CodeIns.RFU_NEW_CORE);
            s.Add(CodeIns.RFU_SET_CONFIG, cfg[0], cfg[1], cfg[2], 256);
            s.Add(CodeIns.RFU_DWLD, Common.LOCPATH + "updateNew.sys", cfg[3] + "/update.sys");
            s.Add(CodeIns.RFU_GET_DIR, cfg[3]);
            s.Add(CodeIns.RFU_END);

            CodeProcessor p = new CodeProcessor();
            p.ProcessCompleted += new EventHandler(delegate
            {
                if (p.State == ProcessorFlag.DataRdyErr ||
                    p.State == ProcessorFlag.Error ||
                    p.State == ProcessorFlag.ReadyErr)
                {
                    _errMsg = p.GetProcessorMessage;
                    _hasError = true;
                    p.ClearErrorFlag();
                    return;
                }
                //If download is successful save the file list to array and check if files must be downloaded.
                DataCache d;
                p.DataFetch(out d);
                d.SetActivePage(0);
                FileList.Clear();
                for (int i = 0; i < d.GetRecordCount(0); i++)
                {
                    if (d.GetValue(i, 1).ToString().Equals("file"))
                    {
                        FileList.Add(d.GetValue(i, 0).ToString());
                    }
                }
            });
            p.Run(s);
        }
        
    }
}